package com.lineage.commons.system;

import com.lineage.config.ConfigIpCheck;
import com.lineage.echo.ClientExecutor;
import com.lineage.server.datatables.lock.IpReading;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class IpAttackCheck {
  public static final Map<ClientExecutor, String> SOCKETLIST;
  
  private static final Log _log = LogFactory.getLog(IpAttackCheck.class);
  
  private static final HashMap<String, IpTemp> _ipList;
  
  private static IpAttackCheck _instance;
  
  static {
    SOCKETLIST = new ConcurrentHashMap<>();
    _ipList = new HashMap<>();
  }
  
  private IpAttackCheck() {
    _ipList.clear();
  }
  
  public static IpAttackCheck get() {
    if (_instance == null)
      _instance = new IpAttackCheck(); 
    return _instance;
  }
  
  public boolean check(String key) {
    try {
      long nowtime = System.currentTimeMillis();
      IpTemp value = _ipList.get(key);
      if (value == null) {
        value = new IpTemp();
        value._time = nowtime;
        value._count = 1;
        _ipList.put(key, value);
        _log.warn("初始连接次数: " + value._count);
      } else if (nowtime - value._time <= ConfigIpCheck.TIMEMILLIS) {
        IpTemp ipTemp = value;
        ipTemp._count++;
        _log.warn("IP: " + key + " 连接间隔不正常 错误次数为: " + value._count);
        if (value._count >= ConfigIpCheck.COUNT) {
          _log.warn("连接间隔不正常 错误次数为: " + value._count + " 封锁IP: " + key);
          kick(key);
          if (ConfigIpCheck.SETDB) {
            IpReading.get().add(key, "IP类似攻击行为");
            System.out.println("IP类似攻击行为" + key);
            return false;
          } 
        } 
      } else {
        value._time = nowtime;
        value._count = 1;
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
    return true;
  }
  
  private void kick(String key) {
    try {
      Iterator<ClientExecutor> iterator = SOCKETLIST.keySet().iterator();
      while (iterator.hasNext()) {
        ClientExecutor socket = iterator.next();
        String ip = SOCKETLIST.get(socket);
        if (ip != null && ip.equals(key))
          socket.close(); 
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  private class IpTemp {
    long _time;
    
    int _count;
    
    private IpTemp() {}
  }
}
